const Database = require('better-sqlite3');
const path = require('path');
const {app} = require('@electron/remote');
import {logger} from '@/utils/logger';

/**
 * 图表数据存储工具类
 * 用于保存和查询PLC采集的图表数据
 */
class ChartDataMapper {
    constructor() {
        this.dbPath = path.join(app.getPath('userData'), 'chart_data.db');
        this.db = null;
        this.init();
    }

    /**
     * 初始化数据库连接和表结构
     */
    init() {
        try {
            this.db = new Database(this.dbPath);
            logger.info(`图表数据库连接成功: ${this.dbPath}`);

            // 创建图表数据表
            this.db.exec(`
                CREATE TABLE IF NOT EXISTS chart_data (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    sn TEXT,
                    timestamp INTEGER NOT NULL,
                    data_values TEXT NOT NULL,
                    session_id TEXT
                )
            `);

            // 创建索引以提高查询性能
            this.db.exec(`
                CREATE INDEX IF NOT EXISTS idx_chart_data_timestamp ON chart_data(timestamp);
                CREATE INDEX IF NOT EXISTS idx_chart_data_sn ON chart_data(sn);
                CREATE INDEX IF NOT EXISTS idx_chart_data_session ON chart_data(session_id);
            `);

            logger.info('图表数据表初始化完成');
        } catch (error) {
            logger.error(`图表数据库初始化失败: ${error.message}`);
        }
    }

    /**
     * 保存一条图表数据
     * @param {string|null} sn 产品条码/序列号
     * @param {Object} dataValues 包含多个监控地址值的对象
     * @param {string|null} sessionId 会话ID
     * @returns {number|null} 插入记录的ID
     */
    saveChartData(sn, dataValues, sessionId = null) {
        try {
            const timestamp = Date.now(); // 毫秒级时间戳
            const dataValuesJson = JSON.stringify(dataValues);

            const stmt = this.db.prepare(`
                INSERT INTO chart_data (sn, timestamp, data_values, session_id)
                VALUES (?, ?, ?, ?)
            `);
            
            const info = stmt.run(
                sn || null,
                timestamp,
                dataValuesJson,
                sessionId || null
            );

            logger.info(`[图表数据] 已保存数据点, ID: ${info.lastInsertRowid}`);
            return info.lastInsertRowid;
        } catch (error) {
            logger.error(`[图表数据] 保存失败: ${error.message}`);
            return null;
        }
    }

    /**
     * 批量保存多条图表数据
     * @param {Array} dataEntries 数据条目数组，每个条目包含 {sn, dataValues, sessionId}
     * @returns {number} 成功插入的记录数
     */
    saveBatchChartData(dataEntries) {
        try {
            const stmt = this.db.prepare(`
                INSERT INTO chart_data (sn, timestamp, data_values, session_id)
                VALUES (?, ?, ?, ?)
            `);

            let successCount = 0;
            const timestamp = Date.now(); // 所有记录使用相同的时间戳

            // 开始事务
            const transaction = this.db.transaction((entries) => {
                for (const entry of entries) {
                    const dataValuesJson = JSON.stringify(entry.dataValues);
                    stmt.run(
                        entry.sn || null,
                        timestamp,
                        dataValuesJson,
                        entry.sessionId || null
                    );
                    successCount++;
                }
                return successCount;
            });

            // 执行事务
            const result = transaction(dataEntries);
            logger.info(`[图表数据] 已批量保存 ${result} 条数据点`);
            return result;
        } catch (error) {
            logger.error(`[图表数据] 批量保存失败: ${error.message}`);
            return 0;
        }
    }

    /**
     * 按时间范围查询数据
     * @param {number} startTime 开始时间戳（毫秒）
     * @param {number} endTime 结束时间戳（毫秒）
     * @param {string|null} sn 产品条码/序列号
     * @returns {Array} 查询结果数组
     */
    getDataByTimeRange(startTime, endTime, sn = null) {
        try {
            let query = 'SELECT * FROM chart_data WHERE timestamp >= ? AND timestamp <= ?';
            const params = [startTime, endTime];

            if (sn) {
                query += ' AND sn = ?';
                params.push(sn);
            }

            query += ' ORDER BY timestamp ASC';

            const stmt = this.db.prepare(query);
            const results = stmt.all(...params);

            // 解析JSON数据
            return results.map(row => ({
                ...row,
                data_values: JSON.parse(row.data_values)
            }));
        } catch (error) {
            logger.error(`[图表数据] 查询失败: ${error.message}`);
            return [];
        }
    }

    /**
     * 获取最新的N条数据
     * @param {number} limit 限制返回的记录数
     * @param {string|null} sn 产品条码/序列号
     * @returns {Array} 查询结果数组
     */
    getLatestData(limit = 100, sn = null) {
        try {
            let query = 'SELECT * FROM chart_data';
            const params = [];

            if (sn) {
                query += ' WHERE sn = ?';
                params.push(sn);
            }

            query += ' ORDER BY timestamp DESC LIMIT ?';
            params.push(limit);

            const stmt = this.db.prepare(query);
            const results = stmt.all(...params);

            // 解析JSON数据并按时间正序返回
            return results.map(row => ({
                ...row,
                data_values: JSON.parse(row.data_values)
            })).reverse();
        } catch (error) {
            logger.error(`[图表数据] 获取最新数据失败: ${error.message}`);
            return [];
        }
    }

    /**
     * 获取特定条码的数据
     * @param {string} sn 产品条码/序列号
     * @param {number} limit 限制返回的记录数
     * @returns {Array} 查询结果数组
     */
    getDataBySN(sn, limit = 1000) {
        try {
            const stmt = this.db.prepare(`
                SELECT * FROM chart_data 
                WHERE sn = ? 
                ORDER BY timestamp DESC 
                LIMIT ?
            `);
            
            const results = stmt.all(sn, limit);

            // 解析JSON数据
            return results.map(row => ({
                ...row,
                data_values: JSON.parse(row.data_values)
            }));
        } catch (error) {
            logger.error(`[图表数据] 获取条码数据失败: ${error.message}`);
            return [];
        }
    }

    /**
     * 清理指定天数之前的数据
     * @param {number} daysToKeep 要保留的天数
     * @returns {number} 清理的记录数
     */
    cleanupOldData(daysToKeep = 30) {
        try {
            const cutoffTime = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);
            
            const stmt = this.db.prepare(`
                DELETE FROM chart_data
                WHERE timestamp < ?
            `);

            const info = stmt.run(cutoffTime);
            logger.info(`[图表数据] 已清理 ${info.changes} 条旧数据`);
            return info.changes;
        } catch (error) {
            logger.error(`[图表数据] 清理失败: ${error.message}`);
            return 0;
        }
    }

    /**
     * 导出数据为CSV格式
     * @param {number} startTime 开始时间戳（毫秒）
     * @param {number} endTime 结束时间戳（毫秒）
     * @param {string|null} sn 产品条码/序列号
     * @returns {string} CSV格式的数据
     */
    exportData(startTime, endTime, sn = null) {
        try {
            const data = this.getDataByTimeRange(startTime, endTime, sn);
            if (data.length === 0) {
                return '';
            }

            // 获取所有可能的数据键
            const allKeys = new Set();
            data.forEach(row => {
                Object.keys(row.data_values).forEach(key => allKeys.add(key));
            });
            const dataKeys = Array.from(allKeys);

            // 创建CSV头
            let csv = ['id,sn,timestamp,date_time,' + dataKeys.join(',')].join('\n');

            // 添加数据行
            data.forEach(row => {
                const dateTime = new Date(row.timestamp).toISOString();
                let line = [
                    row.id,
                    row.sn || '',
                    row.timestamp,
                    dateTime
                ];

                // 添加每个数据键的值
                dataKeys.forEach(key => {
                    line.push(row.data_values[key] !== undefined ? row.data_values[key] : '');
                });

                csv += '\n' + line.join(',');
            });

            return csv;
        } catch (error) {
            logger.error(`[图表数据] 导出失败: ${error.message}`);
            return '';
        }
    }

    /**
     * 获取数据统计信息
     * @param {number} startTime 开始时间戳（毫秒）
     * @param {number} endTime 结束时间戳（毫秒）
     * @param {Array} parameters 要统计的参数列表
     * @param {string|null} sn 产品条码/序列号
     * @returns {Object} 统计信息
     */
    getDataStatistics(startTime, endTime, parameters = [], sn = null) {
        try {
            const data = this.getDataByTimeRange(startTime, endTime, sn);
            if (data.length === 0) {
                return {};
            }

            // 如果没有指定参数，则使用第一条数据中的所有参数
            if (!parameters || parameters.length === 0) {
                parameters = Object.keys(data[0].data_values);
            }

            // 初始化统计对象
            const stats = {};
            parameters.forEach(param => {
                stats[param] = {
                    min: Number.MAX_VALUE,
                    max: Number.MIN_VALUE,
                    sum: 0,
                    count: 0,
                    avg: 0
                };
            });

            // 计算统计值
            data.forEach(row => {
                parameters.forEach(param => {
                    if (row.data_values[param] !== undefined) {
                        const value = parseFloat(row.data_values[param]);
                        if (!isNaN(value)) {
                            stats[param].min = Math.min(stats[param].min, value);
                            stats[param].max = Math.max(stats[param].max, value);
                            stats[param].sum += value;
                            stats[param].count++;
                        }
                    }
                });
            });

            // 计算平均值
            parameters.forEach(param => {
                if (stats[param].count > 0) {
                    stats[param].avg = stats[param].sum / stats[param].count;
                }
                // 如果没有数据，将min设为0
                if (stats[param].min === Number.MAX_VALUE) {
                    stats[param].min = 0;
                }
                // 如果没有数据，将max设为0
                if (stats[param].max === Number.MIN_VALUE) {
                    stats[param].max = 0;
                }
            });

            return stats;
        } catch (error) {
            logger.error(`[图表数据] 统计失败: ${error.message}`);
            return {};
        }
    }

    /**
     * 关闭数据库连接
     */
    close() {
        if (this.db) {
            this.db.close();
            this.db = null;
            logger.info('图表数据库连接已关闭');
        }
    }
}

// 创建单例实例
export const chartDataMapper = new ChartDataMapper();
